#include "IAgent.h"
#include <Clarity/Utils/SharedPtr.h>
#include <Clarity/Platform/DLLInterface.h>

using namespace Clarity;
using namespace AIHarness;
using namespace std;
//using AStar::ANode;

// The following ifdef block is the standard way of creating macros which make exporting 
// from a DLL simpler. All files within this DLL are compiled with the RANDOMBOT_EXPORTS
// symbol defined on the command line. this symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see 
// RANDOMBOT_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef BOT_EXPORTS
#define BOT_API __declspec(dllexport)
#else
#define BOT_API __declspec(dllimport)
#endif

extern "C"
{
   BOT_API void CreateAgent(SharedPtr<IAgent> &agent, AgentInitData agentInitData);
}

/*!
*	Forward Declarations
*/

class Level;
class AStar;
class ANode;
class GraphVisualisation;
class Lines;

class Bot : public DLLImpl<IAgent>
{
public:
   Bot(const AgentInitData &agentInitData);
   virtual ~Bot();

   virtual void Step(const AgentStateIn &agentStateIn, AgentStateOut &agentStateOut);

private:
		enum State
	{
		s_Seek,		//Look for the Enemy
		s_Path,		//Enemy Found, now find a path
		s_Check,	//Check again for the Enemy
		s_Destroy	//Enemy in LoS, Shoot
	};

	void CreateLevel();
	void CreateNodes();
	void ConnectNodes();
	/*!
		Checks other Nodes to see if they exisit between these two nodes
		@return bool True if there is a node between these two
	*/
	bool IsNodeBetween(ANode* s_One, ANode* s_Two) const;
	/*!
		Returns the closest Node to these Co-ordinates
		@param s_Pos The Position to start at
		@return ANode* ANode Pointer closest to the Position Past
	*/
	ANode* ClosestNode(const Vector2 &s_Pos);

	void drawPath();

private:
	State m_State;
	bool m_StartUp;
	const AgentInitData m_agentInitData;
	Vector2 m_Target;
	Vector2 m_TarVelocity;
	Level* m_Level;
	AStar* m_AStar;
	ANode* m_NextNode;		//Current Destination
	/*
	*	DEBUGING
	*/
	GraphVisualisation* m_Nodes;
	Lines *m_Lines;
};
